package org.ithink.util;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.ErrorCode;

/**
 * 扩展JDBCAppender，使其支持数据源
 * 注意数据源有两种：
 * 1、容器控制的：这种JNDI是早就存在的，所以可以配置
 * 2、程序控制的：这种有可能LOG4J在初始化的时候，数据源还没有生成，
 *    所以不适用此扩展
 */
public class JNDIAppender extends JDBCAppender  {
  private String jndiName;

  public String getJndiName() {
    return jndiName;
  }

  public void setJndiName(String jndiName) {
    this.jndiName = jndiName;
  }
  
  /**
   * 根据JNDI得到数据源
   */
	private DataSource lookupDataSource() {

		try {
			Context context = new InitialContext();
			return (DataSource) context.lookup(getJndiName());
		} catch (NamingException e1) {
			try {
				Context context = new InitialContext();
				return (DataSource) context.lookup( "java:comp/env/" + getJndiName());
			} catch (NamingException e2) {
				throw new RuntimeException("Cannot find JNDI DataSource : "
						+ getJndiName(), e2);
			}
		}
	}
  
  /**
   * 重写得到连接的方法
   */
  protected Connection getConnection() throws SQLException {
    if (getJndiName() == null) {
      return super.getConnection();
    } else {
      return lookupDataSource().getConnection();
    }
  }
  
  protected void closeConnection(Connection con) {
    try {
      con.close();
    } catch (SQLException e) {
      errorHandler.error("Failed to close connection", e, ErrorCode.CLOSE_FAILURE);
    }
  }
}